---
title: 서버 아일랜드
description: 고성능 정적 HTML을 동적 서버 렌더링 콘텐츠와 결합하세요.
i18nReady: true
---

서버 아일랜드를 사용하면 페이지의 나머지 부분의 성능을 희생하지 않고도 동적이거나 개인화된 "아일랜드"를 개별적으로 요청 시 렌더링할 수 있습니다.

이는 방문자가 페이지의 가장 중요한 부분을 더 빨리 볼 수 있게 하고, 메인 콘텐츠를 더 적극적으로 캐시할 수 있게 하여 더 빠른 성능을 제공합니다.

## 서버 아일랜드 컴포넌트

서버 아일랜드는 콘텐츠가 사용 가능할 때까지 렌더링을 지연하도록 지시된 일반적인 서버 렌더링 [Astro 컴포넌트](/ko/basics/astro-components/)입니다.

페이지는 지정된 [대체 콘텐츠를 플레이스홀더로](#서버-아일랜드-대체-콘텐츠) 사용하여 즉시 렌더링됩니다. 그런 다음 컴포넌트의 콘텐츠가 클라이언트에서 가져와져 사용 가능할 때 표시됩니다.

[어댑터가 설치된 상태](/ko/guides/on-demand-rendering/#서버-어댑터)에서 지연 렌더링을 수행하기 위해 페이지의 컴포넌트에 [`server:defer` 지시어](/ko/reference/directives-reference/#서버-지시어)를 추가하여 자체 아일랜드로 전환합니다:

```astro title="src/pages/index.astro" "server:defer"
---
import Avatar from '../components/Avatar.astro';
---
<Avatar server:defer />
```

이러한 컴포넌트는 어댑터를 사용하여 콘텐츠를 가져오고 쿠키에 접근하는 등 [요청 시 렌더링되는 페이지에서 일반적으로 할 수 있는 모든 작업](/ko/guides/on-demand-rendering/#요청-시-렌더링-기능)을 수행할 수 있습니다:

```astro title="src/components/Avatar.astro"
---
import { getUserAvatar } from '../sessions';
const userSession = Astro.cookies.get('session');
const avatarURL = await getUserAvatar(userSession);
---
<img alt="User avatar" src={avatarURL} />
```

### 서버 아일랜드에 props 전달하기

서버 아일랜드 컴포넌트에 제공되는 Props는 [직렬화](https://developer.mozilla.org/ko/docs/Glossary/Serialization)할 수 있습니다. 즉, 네트워크를 통해 전송하거나 저장하기에 적합한 형식으로 변환할 수 있어야 합니다. 그리고 Astro는 직렬화 가능한 모든 유형의 데이터 구조를 직렬화하지는 않습니다. 따라서 서버 아일랜드에 props로 전달할 수 있는 항목에는 제한이 있습니다.

특히, 함수는 직렬화할 수 없기 때문에 `server:defer`를 사용하는 컴포넌트에 전달할 수 없습니다. 순환 참조가 있는 객체도 직렬화할 수 없습니다.

지원되는 prop 유형: 
일반 객체, `number`, `string`, `Array`, `Map`, `Set`, `RegExp`, `Date`, `BigInt`, `URL`, `Uint8Array`, `Uint16Array`, `Uint32Array`, `Infinity`

## 서버 아일랜드 대체 콘텐츠

컴포넌트의 렌더링을 지연시키기 위해 `server:defer` 속성을 사용할 때, 포함된 `"fallback"` 이름의 슬롯을 사용하여 기본 로딩 콘텐츠를 "슬롯"할 수 있습니다.

대체 콘텐츠는 페이지 로드 초기에 페이지의 나머지 부분과 함께 렌더링되며, 컴포넌트의 콘텐츠가 사용 가능할 때 해당 콘텐츠로 교체됩니다.

대체 콘텐츠를 추가하려면 서버 아일랜드 컴포넌트에 전달된 자식(다른 컴포넌트나 HTML 요소)에 `slot="fallback"`을 추가하세요:

```astro
---
import Avatar from '../components/Avatar.astro';
import GenericAvatar from '../components/GenericAvatar.astro';
---
<Avatar server:defer>
  <GenericAvatar slot="fallback" />
</Avatar>
```

이 대체 콘텐츠는 다음과 같은 것들이 될 수 있습니다:

- 사용자의 아바타 대신 일반 아바타
- 사용자 정의 메시지와 같은 플레이스홀더 UI
- 스피너와 같은 로딩 표시기


## 작동 방식

서버 아일랜드 구현은 주로 빌드 타임에 이루어지며, 이때 컴포넌트 콘텐츠가 작은 스크립트로 교체됩니다.

`server:defer`로 표시된 각 아일랜드는 런타임에 스크립트가 가져오는 자체 특수 라우트로 분리됩니다. Astro가 사이트를 빌드할 때 컴포넌트를 생략하고 그 자리에 스크립트와 `slot="fallback"`으로 표시한 콘텐츠를 주입합니다.

브라우저에서 페이지가 로드될 때, 이러한 컴포넌트들은 이들을 렌더링하여 HTML을 반환하는 특수 엔드포인트로 요청됩니다. 이는 사용자가 페이지의 가장 중요한 부분을 즉시 볼 수 있다는 것을 의미합니다. 동적 아일랜드가 로드되기 전까지 짧은 시간 동안 대체 콘텐츠가 표시됩니다.

각 아일랜드는 나머지와 독립적으로 로드됩니다. 이는 더 느린 아일랜드가 다른 개인화된 콘텐츠의 사용 가능성을 지연시키지 않는다는 것을 의미합니다.

이 렌더링 패턴은 이식성을 고려하여 만들어졌습니다. 어떤 서버 인프라에도 의존하지 않기 때문에 Docker 컨테이너의 Node.js 서버부터 원하는 서버리스 제공업체까지 모든 호스트에서 작동합니다.

## 캐싱

서버 아일랜드의 데이터는 URL 쿼리에 암호화된 문자열 형태로 props를 전달하는 `GET` 요청을 통해 검색됩니다. 이를 통해 표준 `Cache-Control` 지시어를 사용하여 [`Cache-Control` HTTP 헤더](https://developer.mozilla.org/ko/docs/Web/HTTP/Headers/Cache-Control)로 데이터를 캐싱할 수 있습니다.

하지만 브라우저는 실용적인 이유와 서비스 거부 문제를 방지하기 위해 [URL 길이를 최대 2048바이트로 제한합니다](https://chromium.googlesource.com/chromium/src/+/master/docs/security/url_display_guidelines/url_display_guidelines.md#url-length). 만약 쿼리 문자열로 인해 URL이 이 제한을 초과하게 되면, Astro는 대신 모든 props를 본문에 포함하는 `POST` 요청을 보냅니다.

`POST` 요청은 데이터를 제출하는 데 사용되며 데이터 무결성이나 보안 문제를 일으킬 수 있기 때문에 브라우저에서 캐싱되지 않습니다. 따라서 프로젝트에 있는 기존의 캐싱 로직이 작동하지 않게 됩니다. 가능한 한 서버 아일랜드에 필요한 props만 전달하고, 쿼리를 작게 유지하기 위해 전체 데이터 객체와 배열을 보내는 것을 피하세요.

## 서버 아일랜드의 페이지 URL에 접근

대부분의 경우 서버 아일랜드 컴포넌트는 일반 컴포넌트처럼 [props를 전달](/ko/basics/astro-components/#컴포넌트-props)하여 렌더링하는 페이지에 대한 정보를 얻을 수 있습니다.

하지만 서버 아일랜드는 페이지 요청 외부의 독립된 컨텍스트에서 실행됩니다. 서버 아일랜드 컴포넌트의 `Astro.url`과 `Astro.request.url`은 브라우저의 현재 페이지 URL 대신 `/_server-islands/Avatar`와 같은 URL을 반환합니다. 또한 페이지를 사전 렌더링하는 경우 props로 전달하기 위한 쿼리 매개변수와 같은 정보에 접근할 수 없습니다.

페이지 URL의 정보에 접근하려면 브라우저에서 아일랜드를 로드하는 페이지의 주소가 포함된 [Referer](https://developer.mozilla.org/ko/docs/Web/HTTP/Headers/Referer) 헤더를 확인할 수 있습니다:

```astro
---
const referer = Astro.request.headers.get('Referer');
const url = new URL(referer);
const productId = url.searchParams.get('product');
---
```

## 암호화 키 재사용

Astro는 [cryptography](https://developer.mozilla.org/ko/docs/Glossary/Cryptography)를 사용하여 서버 아일랜드로 전달되는 props를 암호화합니다. 이를 통해 민감한 데이터가 우발적으로 노출되지 않도록 보호합니다. 이 암호화는 각 빌드에서 생성되어 서버 번들에 포함되는 새로운 무작위 키를 사용합니다.

대부분의 배포 호스트는 프런트엔드와 백엔드를 자동으로 동기화합니다. 그러나 롤링 배포, 다중 지역 호스팅 또는 서버 아일랜드가 포함된 페이지를 캐싱하는 CDN을 사용하는 경우 지속적인 암호화 키가 필요할 수 있습니다.

props를 암호화하는 프런트엔드 자산과 이를 복호화하는 백엔드 함수가 일시적으로 다른 키를 사용할 수 있는 롤링 배포 환경 (예: Kubernetes)이나 CDN이 이전 키를 사용하여 빌드된 페이지를 제공하는 경우 서버 아일랜드로 전달된 암호화된 props는 복호화할 수 없습니다.

이러한 상황에서는 Astro CLI를 사용하여 재사용 가능한 인코딩된 암호화 키를 생성하고 이를 빌드 환경의 환경 변수로 설정하세요.

```shell
astro create-key
```

이 값을 사용하여 `ASTRO_KEY` 환경 변수 (예: `.env` 파일)를 구성하고 이를 CI/CD 또는 호스트의 빌드 설정에 포함하세요. 이렇게 하면 생성된 번들에서 항상 동일한 키가 재사용되어 암호화 및 복호화가 동기화됩니다.
